package com.gollum.jpa.util;

import com.gollum.jpa.function.TypeFunction;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * lombda工具类
 * @author Herther
 * @version 1.0.0
 * @ClassName LambdaUtils.java
 * @createTime 2022年09月13日 23:29:00
 */
public class LambdaUtils
{

    /** lombda 类缓存**/
    private static Map<Class, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();

    /**
    * 转换方法引用为属性名
    * @author Herther
    * @Date 11:31 下午 2022/9/13
    * @param fn:
    * @return
    * @version 1.0.0
    **/
    public static <T> String getFieldName(TypeFunction<T> fn) {
        SerializedLambda lambda = getSerializedLambda(fn);
        // 获取方法名
        String methodName = lambda.getImplMethodName();
        String prefix = null;
        if(methodName.startsWith("get")){
            prefix = "get";
        }
        else if(methodName.startsWith("is")){
            prefix = "is";
        }
        if(prefix == null){
            System.out.println("无效的getter方法: "+ methodName);
        }
        // 截取get/is之后的字符串并转换首字母为小写
        return toLowerCaseFirstOne(methodName.replace(prefix, ""));
    }

    /**
    * 实际调用的方法 获取
    * @author Herther
    * @Date 11:30 下午 2022/9/13
    * @version 1.0.0
    **/
    public static SerializedLambda getSerializedLambda(Serializable fn) {
        SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());
        // 先检查缓存中是否已存在
        if(lambda == null) {
            try {
                // 提取SerializedLambda并缓存
                Method method = fn.getClass().getDeclaredMethod("writeReplace");
                method.setAccessible(Boolean.TRUE);
                lambda = (SerializedLambda) method.invoke(fn);
                CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return lambda;
    }

    /**
    * 首字母转小写
    * @author Herther
    * @Date 11:30 下午 2022/9/13
    * @version 1.0.0
    **/
    public static String toLowerCaseFirstOne(String s){
        if(Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }

}
